DEFINE_SYSREG_RW_FUNCS(vpidr_el2)
DEFINE_SYSREG_RW_FUNCS(vmpidr_el2)
+DEFINE_SYSREG_READ_FUNC(isr_el1)
+
/* GICv3 System Registers */
DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el1, ICC_SRE_EL1)
end_afflvl,
mpidr_nodes);
+ /*
+ * Check if all actions needed to safely power down this cpu have
+ * successfully completed. Enter a wfi loop which will allow the
+ * power controller to physically power down this cpu.
+ */
+ if (rc == PSCI_E_SUCCESS)
+ psci_power_down_wfi();
+
return rc;
}
int start_afflvl,
int end_afflvl)
{
+ int skip_wfi = 0;
mpidr_aff_map_nodes_t mpidr_nodes;
unsigned int max_phys_off_afflvl;
end_afflvl,
mpidr_nodes);
+ /*
+ * We check if there are any pending interrupts after the delay
+ * introduced by lock contention to increase the chances of early
+ * detection that a wake-up interrupt has fired.
+ */
+ if (read_isr_el1()) {
+ skip_wfi = 1;
+ goto exit;
+ }
+
/*
* Call the cpu suspend handler registered by the Secure Payload
* Dispatcher to let it do any bookeeping. If the handler encounters an
*/
psci_set_max_phys_off_afflvl(PSCI_INVALID_DATA);
+exit:
/*
* Release the locks corresponding to each affinity level in the
* reverse order to which they were acquired.
psci_release_afflvl_locks(start_afflvl,
end_afflvl,
mpidr_nodes);
+ if (!skip_wfi)
+ psci_power_down_wfi();
}
/*******************************************************************************
MPIDR_AFFLVL0,
target_afflvl);
- psci_power_down_wfi();
-
/* Reset PSCI power state parameter for the core. */
psci_set_suspend_power_state(PSCI_INVALID_DATA);
return PSCI_E_SUCCESS;
*/
rc = psci_afflvl_off(MPIDR_AFFLVL0, target_afflvl);
- /*
- * Check if all actions needed to safely power down this cpu have
- * successfully completed. Enter a wfi loop which will allow the
- * power controller to physically power down this cpu.
- */
- if (rc == PSCI_E_SUCCESS)
- psci_power_down_wfi();
-
/*
* The only error cpu_off can return is E_DENIED. So check if that's
* indeed the case.